package com.peng.mybatis.binding;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.ClassScanner;
import com.peng.mybatis.session.Configuration;
import com.peng.mybatis.session.SqlSession;
import lombok.extern.slf4j.Slf4j;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 映射注册机
 * 缓存映射工厂，防止反复创建
 */
@Slf4j
public class MapperRegistry {

    private static final Map<Class<?>, MapperProxyFactory<?>> knownMappers = new ConcurrentHashMap<>();

    private final Configuration configuration;

    public MapperRegistry(Configuration configuration) {
        this.configuration = configuration;
    }

    @SuppressWarnings("unchecked")
    public <T> T getMapper(Class<T> mapperInterface, SqlSession sqlSession) {
        MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory<T>) knownMappers.get(mapperInterface);
        Assert.notNull(mapperProxyFactory, "类型{}未创建映射工厂", mapperInterface);
        log.info("为类型【{}】创建工厂", mapperInterface.getName());
        return mapperProxyFactory.newInstance(sqlSession);
    }

    public <T> void addMapper(Class<T> mapperInterface) {
        Assert.isFalse(knownMappers.containsKey(mapperInterface),
                "类型{}已经注册: {}", mapperInterface.getName());
        log.info("添加类型【{}】到工厂", mapperInterface.getName());
        knownMappers.put(mapperInterface, new MapperProxyFactory<>(mapperInterface));
    }

    public void addMappers(String packageName) {
        log.info("为包【{}】创建工厂", packageName);
        ClassScanner.scanPackage(packageName).forEach(this::addMapper);
    }

}
